package com.guangfeng.yql.comm.netty.cv;

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.thread.ThreadUtil;
import lombok.SneakyThrows;
import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.ffmpeg.global.avutil;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.Frame;

import java.io.BufferedReader;
import java.nio.charset.StandardCharsets;

public class JavaCVParseUtils {

    public static boolean exit = false;
    private static FFmpegFrameGrabber grabber;
    private static FFmpegFrameRecorder recorder;

    public static void rtsp2Rtmp(String rtsp, String rtmp) {
        new Thread(() -> {
            push(rtsp, rtmp);
        });
    }

    @SneakyThrows
    public static FFmpegFrameGrabber createPull(String url) {
        grabber = FFmpegFrameGrabber.createDefault(url);
        if (url.startsWith("rtsp://")) {
            grabber.setOption("rtsp_transport", "tcp"); // tcp方式防止丢包
        } else if (url.startsWith("rtmp://")) {
            grabber.setOption("rtmp_transport", "tcp"); // tcp方式防止丢包
        }
        return grabber;
    }

    private static void push(String rtspUrl, String rtmpUrl) {
        try {
            int width = 1920, height = 1080;
            grabber = FFmpegFrameGrabber.createDefault(rtspUrl);
            grabber.setOption("rtsp_transport", "tcp"); // tcp方式防止丢包
            grabber.setImageWidth(width);
            grabber.setImageHeight(height);
            grabber.start();
            recorder = new FFmpegFrameRecorder(rtmpUrl, width, height, grabber.getAudioChannels());
            recorder.setInterleaved(true);
            recorder.setVideoOption("tune", "zerolatency"); // 降低编码延时
            recorder.setVideoOption("preset", "ultrafast"); // 提升编码速度
            recorder.setVideoOption("crf", "28"); // 视频质量参数(详见 https://trac.ffmpeg.org/wiki/Encode/H.264)
            recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
            recorder.setFormat("flv"); // 封装格式flv rtmp使用
            recorder.setVideoBitrate(2000000);
            recorder.setFrameRate(25); // 视频帧率(保证视频质量的情况下最低25，低于25会出现闪屏)
            recorder.setPixelFormat(-1);
            recorder.setAudioQuality(-1);// 最高质量
            recorder.setAudioBitrate(192000);// 音频比特率
            recorder.setSampleRate(44100);// 音频采样率
            recorder.setAudioChannels(grabber.getAudioChannels());// 双通道(立体声) 2（立体声）；1（单声道）；0（无音频）
            recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);// 音频编/解码器
            recorder.start();
            avutil.av_log_set_level(avutil.AV_LOG_ERROR);
            while (!exit) {
                Frame frame = grabber.grabImage();
                if (frame == null) {
                    grabber.start();
                    continue;
                }
                recorder.record(frame);
            }

            recorder.stop();
            recorder.release();
            grabber.stop();
            grabber.release();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @SneakyThrows
    public static void main(String[] args) {
//        push("rtsp://admin:hk123456@192.168.1.10:554/Streaming/Channels/1", "rtmp://localhost:1935/hls/123123");
        Process process = Runtime.getRuntime().exec("ffmpeg  -rtsp_transport tcp  -i rtsp://admin:hk123456@192.168.1.10:554/Streaming/Channels/1 -vcodec libx264 -acodec aac -f flv rtmp://192.168.1.77:1935/hls/movie");
        ThreadUtil.execute(()->{
            BufferedReader reader = IoUtil.getReader(process.getErrorStream(), StandardCharsets.UTF_8); String line = null;
            try {
                while ((line = reader.readLine()) != null) {
                    System.out.println(line);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        process.waitFor();
        process.destroy();
        process.destroyForcibly();

    }
}
